using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Rubikev.Common.Data
{
   /// <summary>
   /// Interface to provide data access
   /// </summary>
   /// <typeparam name="TEntity">The type of the entity</typeparam>
   public interface IDao<TEntity> where TEntity : IEntity
   {
      /// <summary>
      /// Gets the entities matching the optional filter, or all entites if no filter is specified
      /// </summary>
      /// <param name="propertiesToFetch">The properties to eagerly load</param>
      /// <returns>The entities matching the filter</returns>
      IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, params Expression<Func<TEntity, object>>[] propertiesToFetch);

      /// <summary>
      /// Adds the <paramref name="entity"/> if it is new, else updates it
      /// </summary>
      /// <param name="entity">The entity to add or update</param>
      /// <returns>The added or updated entity, following the operation</returns>
      TEntity AddOrUpdate(TEntity entity);

      /// <summary>
      /// Deletes the <paramref name="entity"/>
      /// </summary>
      /// <param name="entity">The entity to delete</param>
      void Delete(TEntity entity);

      /// <summary>
      /// Removes the entity from the session so that its changes are no longer tracked
      /// </summary>
      /// <param name="entity">The entity to evict</param>
      void Evict(TEntity entity);

      /// <summary>
      /// The session used for the DAO
      /// </summary>
      ISession Session { get; }
   }
}